<?php

namespace App\Models;

use Cache;

class Menu extends BaseModel
{
    protected $table = "menu";

    public $timestamps = false;

    const DB_MENU_DATA = 'DB_MENU_DATA';
    const DB_MENU_ALL_DATA = 'DB_MENU_ALL_DATA';

    protected $rules = [
        'title' => 'required',
        'url' => 'required',
    ];

    protected $message = [
        'title.required' => '标题必须填写',
        'url.required' => '链接必须填写',
    ];

    /**
     * 获取配置列表
     * @return array 配置数组
     */
    public function getCache()
    {
        $menus = Cache::get(self::DB_MENU_DATA);
        if (!$menus) {
            $where['status'] = 1;
            $where['hide'] = 0;
            $res = $this->_getList($where);
            if ($res) {
                $res = $res->toArray();
                $menus = [];
                foreach ($res as $v) {
                    $menus[$v['id']] = $v;
                }
            }
            Cache::forever(self::DB_MENU_DATA, $menus);
        }
        return $menus;
    }

    /**
     * 获取配置列表
     * @return array 配置数组
     */
    public function getALLCache()
    {
        $menus = Cache::get(self::DB_MENU_ALL_DATA);
        if (!$menus) {
            $menus = $this->_getList();
            if ($menus) {
                $res = $menus->toArray();
                $menus = [];
                foreach ($res as $v) {
                    $menus[$v['id']] = $v;
                }
            }
            Cache::forever(self::DB_MENU_ALL_DATA, $menus);
        }
        return $menus;
    }

    public function generate()
    {
        Cache::forget(self::DB_MENU_ALL_DATA);
        Cache::forget(self::DB_MENU_DATA);
    }

    public function getMenus()
    {
        $data = [];
        $menus = $this->getCache();
        if (is_administrator()) {
            $menus = $this->getALLCache();
        } else {
            $groupAccess = new AuthGroupAccess();
            $res = $groupAccess->getAdminGroupRulesById(session('admin.id'));
            if (!($res && isset($res['group']['rules']))) {
                return false;
            }
            $rules = explode(',', $res['group']['rules']);
            $temp = [];
            foreach ($menus as $k => $v) {
                if (!in_array($k, $rules)) {
                    unset($menus[$k]);
                } else {
                    $temp[] = $v['url'];
                }
            }
            $data['rules'] = $temp;
        }
        if (!($menus && is_array($menus))) {
            return false;
        }
        $menus = sortArrayAsc(levelTree($menus, 'id', 'pid'));
        foreach ($menus as $k => $v) {
            $data['top'][$k]['title'] = $v['title'];
            $data['top'][$k]['rules'][] = $v['url'];
            if ($v['child']) {
                $v['child'] = sortArrayAsc($v['child']);
                foreach ($v['child'] as $j => $m) {
                    $data['top'][$k]['rules'][] = $data['left'][$k]['rules'][] = $m['url'];
                    $data['left'][$k]['data'][$m['group']][$j] = ['title' => $m['title'], 'url' => $m['url']];
                    if ($m['child']) {
                        $m['child'] = sortArrayAsc($m['child']);
                        foreach ($m['child'] as $a => $b) {
                            $data['top'][$k]['rules'][] = $data['left'][$k]['rules'][] = $b['url'];
                            $data['left'][$k]['data'][$m['group']][$j]['rules'][] = $b['url'];
                        }
                    } else {
                        $data['left'][$k]['data'][$m['group']][$j]['rules'] = [];
                    }
                }
            }
        }
        return $data;
    }

    public function getAdminMenus()
    {
        return session('menus');
    }

    public function getMenuList()
    {
        $pid = request('pid', 0);
        $res = [];
        if ($pid) {
            $res['data'] = $this->_getOne(['id' => $pid])->toArray();
        }
        $title = trim(request('title'));
        $menus = $this->getALLCache();
        $where['pid'] = $pid;
        if ($title) {
            $where['title'] = ['like', '%' . $title . '%'];
        }
        $res['list'] = $this->_getList($where, '*', ['sort' => 'asc', 'id' => 'asc'])->toArray();
        int_to_string($res['list'], ['hide' => [1 => '是', 0 => '否']]);
        if ($res['list']) {
            foreach ($res['list'] as &$key) {
                if ($key['pid']) {
                    $key['up_title'] = $menus[$key['pid']]['title'];
                }
            }
        }
        return $res;
    }

    public function getMenuTree()
    {
        $menus = $this->_getList()->toArray();
        $menus = childTree($menus, 0, 'id', 'pid');
        $menus = array_merge([0 => ['id' => 0, 'title' => '顶级菜单', 'prefix' => '']], $menus);
        return $menus;
    }

    public function addOrUpdate()
    {
        $data['title'] = trim(request('title'));
        $data['url'] = trim(request('url'));
        if (request()->has('id')) {
            $data['id'] = trim(request('id'));
        }
        if (!$this->_validate($data)) {
            return false;
        }
        $data['pid'] = request('pid', 0);
        $data['hide'] = request('hide', 0);
        $data['group'] = trim(request('group'));
        $data['status'] = trim(request('status', 1));
        $data['sort'] = trim(request('sort', 0));
        $res = $this->_save($data);
        if ($res) {
            $id = isset($data['id']) ? $data['id'] : $this->id;
            //记录行为
            $actionLog = new ActionLog();
            $actionLog->action_log('update_menu', 'menu', $id, session('admin.id'));
            $this->generate();
        }
        return $res;
    }

    public function del()
    {
        $id = request('id');
        $id = is_array($id) ? $id : [$id];
        $id = array_unique($id);
        if (empty($id)) {
            $this->error = '请选择要操作的数据!';
            return false;
        }
        $where['id'] = ['in', $id];
        $res = $this->_del($where);
        if (!$res) {
            $this->error = '删除失败!';
            return false;
        }
        //记录行为
        $actionLog = new ActionLog();
        $actionLog->action_log('update_menu', 'menu', implode(',', $id), session('admin.id'));
        $this->generate();
        return '删除成功';
    }

    public function importFile()
    {
        $pid = request('pid', 0);
        $tree = file_get_contents(request()->file());
        if (!is_array($tree)) {
            $this->error = '上传文件格式错误！';
            return false;
        }
        $data = [];
        foreach ($tree as $value) {
            $data[] = [
                'title' => $value['title'],
                'url' => $value['url'],
                'pid' => $pid,
                'hide' => isset($value['hide']) ? (int)$value['hide'] : 0,
                'group' => $value['group'],
            ];
        }
        if (empty($data)) {
            $this->error = '请按格式填写批量导入的菜单，至少一个菜单！';
            return false;
        }
        $res = $this->_add($data);
        if (!$res) {
            $this->error = '导入菜单失败！';
            return false;
        }
        return '导入菜单成功！';
    }

    public function import()
    {
        $tree = request('tree');
        $menus = explode(PHP_EOL, $tree);
        if (empty($menus)) {
            $this->error = '请按格式填写批量导入的菜单，至少一个菜单';
            return false;
        }
        $pid = request('pid');
        $data = [];
        foreach ($menus as $k => $v) {
            $record = explode('|', $v);
            if (count($record) == 2) {
                $data[] = [
                    'title' => $record[0],
                    'url' => $record[1],
                    'pid' => $pid,
                    'sort' => 0,
                    'hide' => 0,
                    'group' => '',
                ];
            }
        }
        $res = $this->_add($data);
        if (!$res) {
            $this->error = '导入菜单失败！';
            return false;
        }
        return '导入菜单成功！';
    }

}
